﻿namespace Atomic.Plugins.Files
{
    using System;
    using System.Linq;
    using System.Collections.Generic;
    using System.IO;
    using System.Web.Hosting;
    using System.Web;

    /// <summary>
    /// 默认虚拟路径提供程序。
    /// </summary>
    public class DefaultVirtualPathProvider : IVirtualPathProvider
    {
        /// <summary>
        /// 将路径数组组合成一个路径。
        /// </summary>
        /// <param name="paths">路径数组。</param>
        /// <returns>路径。</returns>
        public string Combine(params string[] paths)
        {
            return Path.Combine(paths).Replace(Path.DirectorySeparatorChar, '/');
        }

        /// <summary>
        /// 将虚拟路径转换成物理路径。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>物理路径。</returns>
        public string MapPath(string virtualPath)
        {
            return HostingEnvironment.MapPath(virtualPath);
        }

        /// <summary>
        /// 判断文件是否存在于虚拟系统里。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>文件是否存在。</returns>
        public bool FileExists(string virtualPath)
        {
            return HostingEnvironment.VirtualPathProvider.FileExists(virtualPath);
        }

        /// <summary>
        /// 从虚拟文件系统里获取一个虚拟文件并打开。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>流</returns>
        public Stream OpenFile(string virtualPath)
        {
            return HostingEnvironment.VirtualPathProvider.GetFile(virtualPath).Open();
        }

        /// <summary>
        /// 创建一个文本文件。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns></returns>
        public StreamWriter CreateText(string virtualPath)
        {
            return File.CreateText(MapPath(virtualPath));
        }

        /// <summary>
        /// 创建一个文件。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns></returns>
        public Stream CreateFile(string virtualPath)
        {
            return File.Create(MapPath(virtualPath));
        }

        /// <summary>
        /// 返回上次写入指定的文件或目录的日期和时间，其格式为协调世界时 (UTC)。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>UTC 时间。</returns>
        public DateTime GetFileLastWriteTimeUtc(string virtualPath)
        {
            return File.GetLastWriteTimeUtc(MapPath(virtualPath));
        }

        /// <summary>
        /// 判断目录是否存在于虚拟系统里。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>目录是否存在。</returns>
        public bool DirectoryExists(string virtualPath)
        {
            return HostingEnvironment.VirtualPathProvider.DirectoryExists(virtualPath);
        }

        /// <summary>
        /// 创建目录。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        public void CreateDirectory(string virtualPath)
        {
            Directory.CreateDirectory(MapPath(virtualPath));
        }

        /// <summary>
        /// 获得目录名称。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        /// <returns>目录名称。</returns>
        public string GetDirectoryName(string virtualPath)
        {
            return Path.GetDirectoryName(virtualPath).Replace(Path.DirectorySeparatorChar, '/');
        }

        /// <summary>
        /// 删除目录。
        /// </summary>
        /// <param name="virtualPath">虚拟路径。</param>
        public void DeleteDirectory(string virtualPath)
        {
            Directory.Delete(MapPath(virtualPath));
        }

        /// <summary>
        /// 指定路径的所有文件列表。
        /// </summary>
        /// <param name="path">路径。</param>
        /// <returns>文件列表。</returns>
        public IEnumerable<string> ListFiles(string path)
        {
            return HostingEnvironment
                .VirtualPathProvider
                .GetDirectory(path)
                .Files
                .OfType<VirtualFile>()
                .Select(f => VirtualPathUtility.ToAppRelative(f.VirtualPath));
        }

        /// <summary>
        /// 指定路径的所有子目录列表。
        /// </summary>
        /// <param name="path">路径。</param>
        /// <returns>目录列表。</returns>
        public IEnumerable<string> ListDirectories(string path)
        {
            return HostingEnvironment
                .VirtualPathProvider
                .GetDirectory(path)
                .Directories
                .OfType<VirtualDirectory>()
                .Select(d => VirtualPathUtility.ToAppRelative(d.VirtualPath));
        }
    }
}